Security hardening batch: updater attestation opt-out, recovery backup, feed repoint, trust-pin TODO#307
Merged
Merged
Conversation
Threads updater.Config.SkipAttestation (present in pinned updater v0.2.2) through a --skip-attestation flag plus a PILOT_UPDATER_SKIP_ATTESTATION env fallback, mirroring the existing --state-path pattern. Default false keeps provenance verification on; the updater fails closed when gh is absent, so hosts genuinely without gh now have an explicit CLI opt-out. Logs a warning when set.
recovery recover replaces the live daemon identity in place via SaveIdentity. Copy any existing identity to identity.json.bak-<unix-ts> first, and refuse the overwrite if the backup cannot be written, so a recovery run can never silently destroy the prior key. Recovery crypto is unchanged. Adds unit tests for the no-file, copy, and unwritable paths.
IsTrusted keys on node_id only, with no pubkey binding. Both web4 call sites are outbound handshake-initiation decisions where the peer's authenticated pubkey is not in scope, so node_id match is all that can be checked locally. Add TODOs documenting that pubkey pinning (IsTrustedWithKey) belongs in the upstream pilot-protocol/trustedagents module at its inbound auto-accept path, where the presented key is available. No behaviour change.
The pilotctl changelog feed pointed at teoslayer.github.io/pilot-changelog, which now 404s after the TeoSlayer to pilot-protocol org rename, and the daemon MOTD feed used the raw TeoSlayer path. Repoint both to the live pilot-protocol locations (pilot-protocol.github.io and raw.githubusercontent.com/pilot-protocol), plus the matching help text and docs. Historical comments, test fixtures, go.sum, and pilot-skills references (whose repo was not migrated) are left as-is.
TeoSlayer
added a commit
that referenced
this pull request
Jun 22, 2026
The updater module v0.2.3 makes SLSA attestation verification fail closed when the gh CLI is absent (previously a silent no-op). Bumping the dependency ships this behavior to the auto-updater binary built by cmd/updater. The --skip-attestation flag (added in #307) continues to wire to updater.Config.SkipAttestation as the explicit opt-out for hosts genuinely without gh. Co-authored-by: Teodor Calin <teodor@vulturelabs.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Batch of confirmed, low-risk security/hardening fixes from a deep-research security audit. All additive and backward-compatible — no breaking protocol changes.
updater:
--skip-attestationflag (H5)The updater module fails closed when
ghis absent (SLSA provenance can't be verified). This threadsupdater.Config.SkipAttestation(present in the pinnedupdater v0.2.2) through a new--skip-attestationflag plus aPILOT_UPDATER_SKIP_ATTESTATIONenv fallback, mirroring the existing--state-pathpattern. Defaultfalsekeeps verification on; logs a warning when set. Gives operators on hosts genuinely withoutghan explicit opt-out.pilotctl: back up identity.json before recovery overwrite (L1)
pilotctl recovery recoverreplaces the live daemon identity in place. Now copies any existing identity toidentity.json.bak-<unix-ts>first and refuses the overwrite if the backup can't be written — an irreversible-overwrite guard. Recovery crypto unchanged. Adds unit tests (no-file / copy / unwritable paths).Repoint runtime changelog + motd feeds (L4)
The pilotctl changelog feed pointed at
teoslayer.github.io/pilot-changelog, which now 404s after theTeoSlayer→pilot-protocolorg rename, and the daemon MOTD feed used the raw TeoSlayer path. Both repointed to the livepilot-protocollocations (verified 200), plus the matching help text and docs. Historical comments, test fixtures,go.sum, andpilot-skillsreferences (that repo was not migrated; redirect still works) left as-is.trustedagents: document pubkey-pinning gap (H4)
trustedagents.IsTrustedkeys onnode_idonly, with no pubkey binding. Thetrustedagentspackage is a separate published module (github.com/pilot-protocol/trustedagents@v0.2.3), not in-repo, and both web4 call sites are outbound handshake-initiation decisions where the peer's authenticated pubkey is not in scope. Added TODOs documenting that pubkey pinning (IsTrustedWithKey+ optionalPublicKeyfield on theAgentstruct + tests) must land in the upstream module at its inbound auto-accept path. No behaviour change here.Validation
GOWORK=off go build ./...,go vet, andgo testpass for the affected packages (cmd/updater,cmd/pilotctl,internal/motd). gofmt -s clean. pre-commit hooks (gitleaks / vet / fmt) green on every commit.